package cn.anecansaitin.whimsy.common.extension.comboSystem;

import net.minecraft.world.entity.player.Player;

/**
 * 可蓄力技能的默认实现。
 * 思路：
 * 将派生出这个技能的按键作为蓄力按键。
 * 也就是说，当canCachingKey()返回true时，玩家按住
 * 对应按键就被视为正在蓄力。如果期间中断了，则表示蓄
 * 力结束，开始后摇。
 */
public interface IChargeableSkill extends ISkill, IChargeable {
    @Override
    default boolean execute(int skillTick, Player player, ExtraData extra) {
        if (skillTick < precastTick()) {
            if (skillTick <= 0) {
                prePrecast(player, extra);
            }

            precast(skillTick, player, extra);
            return false;
        } else if (isCharging(extra) && getChargedTick(extra) <= maxChargingTick()) {
            if (getChargedTick(extra) <= 0) {
                preCharging(player, extra);
            }

            addChargedTick(extra);
            charging(skillTick, player, extra);
            return false;
        } else {
            int backSwingTick = skillTick - getChargedTick(extra);

            if (backSwingTick <= 0) {
                preBackswing(player, extra);
            }

            backswing(skillTick, player, extra);

            if (backSwingTick > backswingTick()) {
                finish(player, extra);
                return true;
            }

            return false;
        }
    }

    /**
     * @return 前摇的持续时间
     */
    int precastTick();

    /**
     * @return 技能最长蓄力的时间
     */
    int maxChargingTick();

    /**
     * @return 后摇的持续时间
     */
    int backswingTick();

    /**
     * 前摇开始前
     */
    void prePrecast(Player player, ExtraData extra);

    /**
     * 前摇执行期间
     */
    void precast(int skillTick, Player player, ExtraData extra);

    /**
     * 蓄力开始前
     */
    void preCharging(Player player, ExtraData extra);

    /**
     * 蓄力期间
     */
    void charging(int skillTick, Player player, ExtraData extra);

    /**
     * 后摇开始前
     */
    void preBackswing(Player player, ExtraData extra);

    /**
     * 后摇执行期间
     */
    void backswing(int skillTick, Player player, ExtraData extra);

    /**
     * 完全结束后
     */
    default void finish(Player player, ExtraData extra) {
        removeCache(extra);
    }
}
